package com.ebupt.migu.music.strategy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ebupt.migu.common.dto.MiguSubCompanyCampDto;
import com.ebupt.migu.music.approve.entity.ApproveHistory;
import com.ebupt.migu.music.approve.mapper.ApproveMapper;
import com.ebupt.migu.music.approve.mapper.SMSApproveRankInfoMapper;
import com.ebupt.migu.music.common.constants.ApproveConstans;
import com.ebupt.migu.music.common.constants.RoleConstants;
import com.ebupt.migu.music.common.constants.StrategyConstants;
import com.ebupt.migu.music.common.constants.UserGroupConstants;
import com.ebupt.migu.music.common.entity.Page;
import com.ebupt.migu.music.common.entity.ResultObject;
import com.ebupt.migu.music.common.exception.MyException;
import com.ebupt.migu.music.common.exception.StatusEnum;
import com.ebupt.migu.music.common.sms.Sender;
import com.ebupt.migu.music.common.util.DateUtil;
import com.ebupt.migu.music.common.util.HttpUtils;
import com.ebupt.migu.music.common.util.JsonUtils;
import com.ebupt.migu.music.megamarket.mapper.MegamarketMapper;
import com.ebupt.migu.music.schedule.mapper.PopupMapper;
import com.ebupt.migu.music.sms.mapper.SmsTmplMapper;
import com.ebupt.migu.music.strategy.entity.SMSApproveRankInfoBean;
import com.ebupt.migu.music.strategy.mapper.StrategyMapper;
import com.ebupt.migu.music.strategy.service.StrategyService;
import com.ebupt.migu.music.system.entity.SysUser;
import com.ebupt.migu.music.system.mapper.RoleMapper;
import com.ebupt.migu.music.unifyAudit.pojo.AuditData;
import com.ebupt.migu.music.unifyAudit.service.UnifyAuditService;
import com.ebupt.migu.music.userGroup.mapper.CrowdMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Intellij IDEA. User: liuyangyang@cd.ebupt.com Date: 2019/9/24
 */
@Slf4j
@Service
public class StrategyServiceImpl implements StrategyService {

    @Autowired
    private StrategyMapper strategyMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private CrowdMapper crowdMapper;
    @Autowired
    private ApproveMapper approveMapper;
    @Autowired
    private SmsTmplMapper smsTmplMapper;
    @Autowired
    private PopupMapper popupMapper;
    @Autowired
    private SMSApproveRankInfoMapper smsApproveRankInfoMapper;
    @Autowired
    private MegamarketMapper megamarketMapper;
    @Resource
    private UnifyAuditService unifyAuditService;

    // 文件默认保存路径
    @Value("${path.file_rcode_path}")
    private String FILE_RECODE_PATH;

    @Value("${megamarket.ip}")
    private String MEGAMARKET_IP;

    @Value("${megamarket.subCompanyCampSync2Marketing}")
    private String MEGAMARKET_SUBCOMPANYCAMPSYNC2MARKETING;

    private final static Integer FILE_SIZE = 40;// 文件上传限制大小
    private final static String FILE_UNIT = "M";// 文件上传限制单位（B,K,M,G）

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 创建策略 1. 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始 2. 如果人群规模大于200，需要审批人审批之后才可以进入运营状态 策略类型：1-短信策略； 2-banner策略； 3-音乐之声；
     * 4-push策略； 5-弹窗策略； 参数验证顺序：1- 策略名称不可为空且不可重名； 2- 策略类型不可为空； 3- 具体的策略类型参数验证；
     *
     * @param params
     * @return
     */
    @Override
    @Transactional
    public ResultObject addStrategy(Map<String, Object> params) {
        List<Map<String, Object>> paramsList = (List<Map<String, Object>>) params.get("strategyList");
        ResultObject res = new ResultObject();
        String strategyGroupId = "SG" + DateUtil.parseDateToStr(new Date(), DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISS);
        String strategyName = null;
        try {
            int num = 0;
            for (Map<String, Object> paramItem : paramsList) {
                num++;
                // 策略名称不可为空
                if (null == paramItem.get("strategyName")) {
                    throw new MyException(StatusEnum.BUSINID, "第" + num + "个策略名称不可为空");
                }
                strategyName = paramItem.get("strategyName").toString().trim();


                // 策略类型不可为空
                if (null == paramItem.get("strategyType")) {
                    throw new MyException(StatusEnum.BUSINID, strategyName + "的策略类型不可为空");
                }

                // 验证push_url格式：只能以 http/https/mgmusic 开头
                if (null != paramItem.get("pushUrl") && !"".equals(paramItem.get("pushUrl").toString().trim())) {
                    String pushUrl = paramItem.get("pushUrl").toString().trim();
                    if (!(pushUrl.startsWith("http") || pushUrl.startsWith("https") || pushUrl.startsWith("mgmusic") || pushUrl.startsWith("mgmedia"))) {
                        throw new MyException(StatusEnum.BUSINID, strategyName + "的消息链接格式错误");
                    }
                }

                // 策略名称不可重复
                Map<String, Object> strMap = new HashMap<>(1);
                strMap.put("strategyName", strategyName);
                boolean isExist = strategyMapper.isExist(strMap);
                if (isExist) {
                    throw new MyException(StatusEnum.STRATEGY_NAME_EXIST, strategyName + "的策略名称已存在");
                }
                paramItem.put("strategyGroupId", strategyGroupId);
                paramItem.put("userID", params.get("userID"));
                paramItem.put("creatorId", params.get("creatorId"));
                paramItem.put("creatorName", params.get("creatorName"));
                paramItem.put("creatorDepartmentId", params.get("creatorDepartmentId"));
                paramItem.put("creatorDepartment", params.get("creatorDepartment"));
                paramItem.put("creatorPhone", params.get("creatorPhone"));
                paramItem.put("creatorEmail", params.get("creatorEmail"));
                HashMap<String, Object> group = new HashMap<>();
                // 新增策略时先查询使用人群的状态
                if (null != paramItem.get("groupId") && !"".equals(paramItem.get("groupId"))) {
                    group = crowdMapper.queryByGroupID(paramItem.get("groupId").toString());
                    paramItem.put("userGroupStatus", Integer.valueOf(group.get("createStatus").toString()));
                } else {
                    paramItem.put("userGroupStatus", 5);
                }
                // 针对不同策略进行参数验证及初始化参数值
                // 1-短信策略； 2-banner策略； 3-音乐之声； 4-push策略； 5-弹窗策略；
                switch (Integer.parseInt(paramItem.get("strategyType").toString())) {
                    case 1:
                        smsStrategy(paramItem);
                        break;
                    case 2:
                        bannerStrategy(paramItem);
                        break;
                    case 3:
                        musicStrategy(paramItem);
                        break;
                    case 4:
                        pushStrategy(paramItem);
                        break;
                    case 5:
                        popupStrategy(paramItem);
                        break;
                    case 6:
                        msgNoticeStrategy(paramItem);
                        break;
                    default:
                        throw new MyException(StatusEnum.BUSINID, strategyName + "策略类型错误");
                }
                strategyMapper.addStrategy(paramItem);
            }
            res.setMsg("创建策略成功！");
            return res;
        } catch (MyException e) {
            log.error(strategyName + "的创建策略相应参数验证失败", e);
            throw e;
        } catch (Exception e) {
            log.error(strategyName + "的创建策略失败", e);
            throw new MyException(StatusEnum.ERROR, strategyName + "的创建策略失败");
        }
    }

    /**
     * 分页、条件查询策略列表 1. 查询限定条件下的总计条数 2. 查询条件： 策略名称、策略类型、创建时间、执行状态、创建人、部门 3. 超级管理员可以查看操作所有部门所创建的人群、 4. 非超级管理员只能查看本部门策略 5.
     * 按照创建时间降序排列
     *
     * @param params
     * @param user
     * @return
     */
    @Override
    public ResultObject strategyList(Map<String, Object> params, SysUser user) {
        ResultObject<Page<HashMap<String, Object>>> res = new ResultObject<>();
        try {
            // 超级管理员可以查询所有运营策略， 非超级管理员仅能查询本部门运营策略
            String userID = user.getId().toString();
            List<String> roles = roleMapper.queryRoleIdByUserId(userID);
            if (!roles.contains(RoleConstants.SUPER_ADMIN) && !roles.contains(RoleConstants.SUPERAIMIN)) {
                // 如果不是系统管理员或超级管理员， 设置查询范围为本部门
                params.put("creatorDepartment", user.getDeptName());
            }

            if (null != params.get("executeStatus") && "7".equals(String.valueOf(params.get("executeStatus")))) {
                params.remove("executeStatus");
            }

            // 总数
            Integer total = strategyMapper.countStrategyList(params);
            // 分页查询结果集
            List<HashMap<String, Object>> datas = strategyMapper.strategyList(params);
            // 遍历查询结果- 将策略中引用的人群信息查询出来
            if (datas.size() != 0) {
                for (HashMap<String, Object> map : datas) {
                    // 人群ID
                    Object groupId = map.get("groupId");
                    if (!"".equals(groupId) && groupId != null) {
                        // 通过人群ID查询人群详情
                        Map<String, Object> groupInfo = crowdMapper.queryByGroupID(groupId.toString());
                        if (null == groupInfo) {
                            continue;
                        }
                        // 当没有大字段的时候，返回空；
                        if (null == groupInfo.get("groupAttribute")) {
                            map.put("groupAttribute", "");
                        } else {
                            map.put("groupAttribute", JSON.toJSONString(groupInfo.get("groupAttribute")));
                        }
                    }
                }
            }
            // 分页
            Page<HashMap<String, Object>> page = new Page<>();
            page.setTotal(total);
            page.setData(datas);
            res.setMsg("查询策略列表成功");
            res.setData(page);
            return res;
        } catch (Exception e) {
            log.error("查询策略列表失败", e);
            throw new MyException(StatusEnum.ERROR, "查询策略列表失败");
        }
    }

    /**
     * 分页、条件查询策略列表 1. 查询限定条件下的总计条数 2. 查询条件： 策略名称、策略类型、创建时间、执行状态、创建人、部门 3. 超级管理员可以查看操作所有部门所创建的人群、 4. 非超级管理员只能查看本部门策略 5.
     * 按照创建时间降序排列
     *
     * @param params
     * @param user
     * @return
     */
    @Override
    public ResultObject strategyListByNameOrId(Map<String, Object> params, SysUser user) {
        ResultObject<Page<Map<String, Object>>> res = new ResultObject<>();
        try {
            // 超级管理员可以查询所有运营策略， 非超级管理员仅能查询本部门运营策略
            String userID = user.getId().toString();
            List<String> roles = roleMapper.queryRoleIdByUserId(userID);
            if (!roles.contains(RoleConstants.SUPER_ADMIN) && !roles.contains(RoleConstants.SUPERAIMIN)) {
                // 如果不是超级管理员， 设置查询范围为本部门
                params.put("creatorDepartment", user.getDeptName());
            }
            // 总数
            Integer total = smsTmplMapper.querySmsTmplCount(params);
            // 分页查询结果集
            List<Map<String, Object>> datas = smsTmplMapper.querySmsTmpl(params);
            // 分页
            Page<Map<String, Object>> page = new Page<>();
            page.setTotal(total);
            page.setData(datas);
            res.setMsg("查询策略列表成功");
            res.setData(page);
            return res;
        } catch (Exception e) {
            log.error("查询策略列表失败", e);
            throw new MyException(StatusEnum.ERROR, "查询策略列表失败");
        }
    }

    /**
     * 删除策略 1. 策略执行状态： 1-待审核；2-已驳回；3-未开始；4-进行中；5-已中止；6-已结束；7-已删除； 2. 仅 2、3、5、6 状态下的策略可以被删除 3. 谁创建、谁删除、谁修改、谁提交
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject deleteStrategy(Map<String, Object> params) {
        ResultObject res = new ResultObject();
        // 策略ID不可为空
        if (null == params.get("strategyId")) {
            throw new MyException(StatusEnum.BUSINID, "策略ID不可为空");
        }
        // 执行状态不可为空
        if (null == params.get("executeStatus")) {
            throw new MyException(StatusEnum.BUSINID, "策略执行状态不可为空");
        }
        // 仅【2-已驳回；3-未开始；5-已中止；6-已结束；8-待提审】状态下的策略可以被删除
        byte executeStatus = Byte.parseByte(params.get("executeStatus").toString());
        if (!(executeStatus == StrategyConstants.EXECUTE_REJECTED
                || executeStatus == StrategyConstants.EXECUTE_UNEXECUTED
                || executeStatus == StrategyConstants.EXECUTE_TERMINATED || executeStatus == StrategyConstants.EXECUTE_ENDED
                || executeStatus == StrategyConstants.EXECUTE_RETRACT)) {
            throw new MyException(StatusEnum.BUSINID, "当前状态的策略不可被删除");
        }
        try {
            strategyMapper.deleteStrategyById(params);
        } catch (Exception e) {
            log.error("删除策略失败", e);
            throw new MyException(StatusEnum.ERROR, "删除策略失败");
        }
        res.setMsg("删除成功");
        return res;
    }

    /**
     * 更新策略信息
     * <p>
     * 业务逻辑修改历史： 2019-10-09 廖明兰- 策略名称不允许修改
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject updateStrategy(Map<String, Object> params) {
        ResultObject res = new ResultObject();
        // 策略ID不可为空
        if (null == params.get("strategyId")) {
            res.setCode(StatusEnum.BUSINID.getCode());
            res.setMsg("策略ID不可为空");
            return res;
        }

        // 是否需要审批
        boolean flag = false;
        HashMap<String, Object> userGroup = new HashMap<>();
        // 新增策略时先查询使用人群的状态
        if (null != params.get("groupId") && !"".equals(params.get("groupId"))) {
            userGroup = crowdMapper.queryByGroupID(params.get("groupId").toString());
        } else {
            userGroup.put("createStatus", 5);
            params.put("clientUser", "9999");
        }
        if (Integer.valueOf(userGroup.get("createStatus").toString()).equals(5)) {
            // 短信策略需要校验手机用户是否超过200人- 小于200人时不需要审批
            if (Byte.parseByte(params.get("strategyType").toString()) == StrategyConstants.TYPE_SMS) {
                // 删除sms_approve_rank_info表的信息
                smsApproveRankInfoMapper.deleteSMSApproveRankInfoByActivityID(String.valueOf(params.get("strategyId")));
                // 写入新的sms_approve_rank_info表的信息
                // 记录短信审核顺序
                List<SMSApproveRankInfoBean> ranks =
                        JSONObject.parseArray(String.valueOf(params.get("ranks")), SMSApproveRankInfoBean.class);
                String sms_content = "";
                String jobType = "";

                // 手机用户
                int mobileUser = Integer.parseInt(params.get("mobileUser").toString());
                if (mobileUser < 200) {
                    // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
                    params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
                    params.put("approverId", null);
                } else {
                    flag = true;

                    params.get("smsContent").toString();

                    // 任务类型：1-立即执行；2-单次执行；3-循环（重复）执行；4-间隔执行；

                    Object object = params.get("jobType").toString();
                    if (object.equals("1")) {
                        jobType = "立即执行";
                    }
                    if (object.equals("2")) {
                        String start_time = params.get("startTime").toString();
                        jobType = start_time;
                    }
                    if (object.equals("3")) {
                        String start_time = params.get("startTime").toString();
                        String end_time = params.get("endTime").toString();
                        jobType = start_time + "至" + end_time;
                    }
                    if (object.equals("4")) {
                        String start_time = params.get("startTime").toString();
                        String end_time = params.get("endTime").toString();
                        String interval_days = params.get("intervalDays").toString();
                        jobType = start_time + "至" + end_time + "间隔:" + interval_days + "天";
                    }

                    if (null != ranks) {
                        for (SMSApproveRankInfoBean rank : ranks) {
                            rank.setActivityId(String.valueOf(params.get("strategyId")));
                            HashMap group = crowdMapper.queryByGroupID(params.get("groupId").toString());
                            // 1号审核人默认为首位审核人，审核状态默认为审核中
                            if ("1".equals(String.valueOf(rank.getRank()))) {
                                rank.setStatus(Byte.valueOf("1").byteValue());
                                params.put("approverId", String.valueOf(rank.getApproverId()));
                                params.put("approverName", String.valueOf(rank.getApproverName()));
                                String mobile = strategyMapper.getMobile(rank.getApproverId());
                                String randomId = getRandomId(params.get("strategyId").toString(), rank.getApproverId());
                                Sender.sendSMS(
                                        Sender.CHECK_CODE,
                                        new String[]{mobile},
                                        new String[]{
                                                params.get("strategyName").toString(),
                                                group.get("mobileUser").toString(),
                                                sms_content,
                                                jobType,
                                                randomId,
                                                randomId,
                                        }
                                );
                            }
                            smsApproveRankInfoMapper.insertSMSApproveRankInfo(rank);
                        }
                    }
                    params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
                }
            }
            if (Byte.parseByte(params.get("strategyType").toString()) == StrategyConstants.TYPE_BANNER
                    || Byte.parseByte(params.get("strategyType").toString()) == StrategyConstants.TYPE_MUSIC
                    || Byte.parseByte(params.get("strategyType").toString()) == StrategyConstants.TYPE_MSG) {
                int size = maxValue(Integer.parseInt(String.valueOf(params.get("clientUser"))),
                        Integer.parseInt(String.valueOf(params.get("deviceUser"))));
                if (size < 200) {
                    // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
                    params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
                    params.put("approverId", null);
                } else {
                    flag = true;
                    params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
                }
            }
            if (Byte.parseByte(params.get("strategyType").toString()) == StrategyConstants.TYPE_PUSH) {
                // 客户端用户
                int clientUser = Integer.parseInt(params.get("clientUser").toString());
                if (clientUser < 200) {
                    // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
                    params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
                    params.put("approverId", null);
                } else {
                    flag = true;
                    params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
                }
            }
            if (Byte.parseByte(params.get("strategyType").toString()) == StrategyConstants.TYPE_POPUP) {
                if ("1".equals(String.valueOf(params.get("popupType")))) {
                    // 客户端用户
                    int clientUser = Integer.parseInt(params.get("clientUser").toString());
                    if (clientUser < 200) {
                        // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
                        params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
                        params.put("approverId", null);
                    } else {
                        flag = true;
                        params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
                    }
                }
                if ("2".equals(String.valueOf(params.get("popupType")))) {
                    // 客户端用户
                    int clientUser = Integer.parseInt(params.get("deviceUser").toString());
                    if (clientUser < 200) {
                        // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
                        params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
                        params.put("approverId", null);
                    } else {
                        flag = true;
                        params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
                    }
                }
            }
        } else {
            flag = true;
            params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
        }
        // 统一审核能力接入
        smsUnifyAudit(params);
        try {
            params.remove("pause");
            params.put("pause", "0");
            strategyMapper.updateStrategy(params);
            // 添加审批记录
            if (flag) {
                createApprove(params);
            }
            res.setMsg("更新策略成功");
            return res;
        } catch (Exception e) {
            log.error("更新策略失败", e);
            throw new MyException(StatusEnum.ERROR, "更新策略失败");
        }
    }

    /**
     * 中止/终止策略执行
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject endExecute(Map<String, Object> params) {
        // 策略ID不可为空
        if (null == params.get("strategyId")) {
            throw new MyException(StatusEnum.BUSINID, "策略ID不可为空");
        }
        try {
            // 中止策略执行
            strategyMapper.endExecute(params);
            ResultObject res = new ResultObject();
            res.setMsg("中止策略成功");
            return res;
        } catch (Exception e) {
            log.error("中止策略失败", e);
            throw new MyException(StatusEnum.ERROR, "中止策略失败");
        }
    }

    /**
     * 重新提交策略 1. 验证当前用户是否超级管理员或者运营策略创建者 2. 验证重新提交的运营策略人群是否超过200人：超过200- 执行状态修改为待审核；未超过200- 执行状态修改为未开始；
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject resubmit(Map<String, Object> params) {
        ResultObject res = new ResultObject();
        // 人群规模为必填参数
        if (null == params.get("userGroupSize")) {
            throw new MyException(StatusEnum.BUSINID, "人群规模参数异常");
        }
        // 人群规模
        int userGroupSize = Integer.parseInt(params.get("userGroupSize").toString());
        // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
        if (userGroupSize < 200) {
            params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
        } else {
            if (null == params.get("approverId") || null == params.get("approverName")) {
                res.setCode(StatusEnum.BUSINID.getCode());
                res.setMsg("请选择审核人");
                return res;
            }
        }
        return null;
    }

    /**
     * 查询策略详情 i 策略审批查看策略详情 ii 查看策略关联的人群的详情
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject detail(Map<String, Object> params) {
        if (null == params.get("strategyId") || "".equals(params.get("s"))) {
            throw new MyException(StatusEnum.BUSINID, "strategyId不可为空");
        }
        Map<String, Object> strategy = new HashMap<>();
        ResultObject res = new ResultObject();
        String strategyId = params.get("strategyId").toString();
        try {
            strategy = strategyMapper.queryByStrategyId(strategyId);
            // 针对会员弹窗 全客户端不需要关联人群 单独返回
            Object vipTargetCrowd = strategy.get("vipTargetCrowd");
            if ("7".equals(strategy.get("strategyType").toString()) && !"".equals(vipTargetCrowd)
                    && "1".equals(strategy.get("vipTargetCrowd").toString())) {
                strategy.put("groupInfo", "");
                res.setMsg("查询策略详情成功");
                res.setData(strategy);
                return res;
            }
            if (1 == Integer.valueOf(String.valueOf(strategy.get("broadcastPush")))) {
                strategy.put("groupInfo", "");
                res.setMsg("查询策略详情成功");
                res.setData(strategy);
                return res;
            }
            // 查询当前策略中引用的人群的详情
            String gid = strategy.get("groupId").toString();
            Map<String, Object> data = crowdMapper.queryByGroupID(gid);
            // 当前人群如果是由人群重组生成的，继续向下查询参与重组的人群
            // 创建方式是否符合重组创建
            byte createWay = Byte.valueOf(data.get("createWay").toString());
            if (createWay == UserGroupConstants.RECOMBINE_BY_INTERSECT
                    || createWay == UserGroupConstants.RECOMBINE_BY_UNION
                    || createWay == UserGroupConstants.RECOMBINE_BY_DIFF_LEFT
                    || createWay == UserGroupConstants.RECOMBINE_BY_DIFF_RIGHT
                    || createWay == UserGroupConstants.RECOMBINE_BY_DIFF_SYMMETRIC) {
                // 向下查询参与重组的人群
                String[] ids = data.get("resGroups").toString().split(",");
                // TODO: web二期需要展示所有级联重组人群，暂时将返回结果构造成如下形式，避免页面改动过大
                List<HashMap<String, Object>> recombines = new ArrayList<>();
                HashMap<String, Object> recombine = new HashMap<>();
                recombine.put("name", data.get("userGroupName"));
                // 查询并保存参与重组的人群的名称
                for (int i = 0; i < ids.length; i++) {
                    HashMap<String, Object> map = crowdMapper.queryByGroupID(ids[i]);
                    if (map == null) {
                        break;
                    }
                    recombine.put("group" + (i + 1), map.get("userGroupName"));
                }
                // 自定义命名
                if (null == recombine.get("group1")) {
                    recombine.put("group1", "未查找到人群名称或人群已经不存在");
                    recombine.put("group2", "未查找到人群名称或人群已经不存在");
                }
                switch (createWay) {
                    case UserGroupConstants.RECOMBINE_BY_INTERSECT:
                        recombine.put("way", "交集");
                        recombines.add(recombine);
                        data.put("recombine", recombines);
                        break;
                    case UserGroupConstants.RECOMBINE_BY_UNION:
                        recombine.put("way", "并集");
                        recombines.add(recombine);
                        data.put("recombine", recombines);
                        break;
                    case UserGroupConstants.RECOMBINE_BY_DIFF_LEFT:
                        recombine.put("way", "左差集");
                        recombines.add(recombine);
                        data.put("recombine", recombines);
                        break;
                    case UserGroupConstants.RECOMBINE_BY_DIFF_RIGHT:
                        recombine.put("way", "右差集");
                        recombines.add(recombine);
                        data.put("recombine", recombines);
                        break;
                    case UserGroupConstants.RECOMBINE_BY_DIFF_SYMMETRIC:
                        recombine.put("way", "对称差集");
                        recombines.add(recombine);
                        data.put("recombine", recombines);
                        break;
                    default:
                        recombine.put("way", "重组方式信息有误");
                        recombines.add(recombine);
                        data.put("recombine", recombines);
                        break;
                }
            }
            strategy.put("groupInfo", data);
            res.setMsg("查询策略详情成功");
            res.setData(strategy);
            return res;
        } catch (Exception e) {
            log.error("查询策略详情失败", e);
            throw new MyException(StatusEnum.ERROR, "查询策略详情失败");
        }
    }

    /**
     * 短信策略参数验证及业务逻辑
     *
     * @param params
     * @return
     */
    private void smsStrategy(Map<String, Object> params) throws IOException {
        // 生成策略ID
        Date date = new Date();
        String strategyId = "DX" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        params.put("strategyId", strategyId);
        // 已完成的人群当人群规模小于200时跳过审批
        if (params.get("userGroupStatus").equals(5)) {
            // 人群规模为必填参数
            if (null == params.get("mobileUser")) {
                throw new MyException(StatusEnum.BUSINID, "请填写人群规模");
            }
            // 人群规模
            int userGroupSize = Integer.parseInt(params.get("mobileUser").toString());
            // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
            noApprove(params, userGroupSize);

        } else {
            if (null == params.get("approverId") || null == params.get("approverName")) {
                throw new MyException(StatusEnum.BUSINID, "请选择审核人");
            }
        }
        // 统一审核能力接入
        smsUnifyAudit(params);
    }

    /**
     * 已经完成且规模小于200的人群不需要审批
     *
     * @param params        数据信息
     * @param userGroupSize 人群规模
     */
    private void noApprove(Map<String, Object> params, int userGroupSize) {
        if (userGroupSize <= 200) {
            params.put("executeStatus", StrategyConstants.EXECUTE_UNEXECUTED);
            params.put("approverId", null);
        } else {
            if (null == params.get("approverId") || null == params.get("approverName")) {
                throw new MyException(StatusEnum.BUSINID, "请选择审核人");
            }

            byte strategyType = Byte.valueOf(params.get("strategyType").toString());
            String sms_content = "";
            String jobType = "";
            if (strategyType == StrategyConstants.TYPE_SMS) {
                sms_content = params.get("smsContent").toString();
                String start_time = params.get("startTime").toString();
                String end_time = params.get("endTime").toString();
                String interval_days = params.get("intervalDays").toString();
                // 任务类型：1-立即执行；2-单次执行；3-循环（重复）执行；4-间隔执行；
                Object object = params.get("jobType");
                if (object.equals("1")) {
                    jobType = "立即执行";
                }
                if (object.equals("2")) {
                    jobType = start_time;
                }
                if (object.equals("3")) {
                    jobType = start_time + "至" + end_time;
                }
                if (object.equals("4")) {
                    jobType = start_time + "至" + end_time + "间隔:" + interval_days + "天";
                }
            }
            String strategyID = String.valueOf(params.get("strategyId"));
            // 记录短信审核顺序
            List<SMSApproveRankInfoBean> ranks = JSONObject.parseArray(String.valueOf(params.get("ranks")), SMSApproveRankInfoBean.class);
            if (null != ranks) {
                for (SMSApproveRankInfoBean rank : ranks) {
                    rank.setActivityId(strategyID);
                    // 1号审核人默认为首位审核人，审核状态默认为审核中
                    if ("1".equals(String.valueOf(rank.getRank()))) {
                        //创建审核记录待审核
                        rank.setStatus(Byte.valueOf("1").byteValue());
                        params.put("approverId", String.valueOf(rank.getApproverId()));
                        params.put("approverName", String.valueOf(rank.getApproverName()));
                        String mobile = strategyMapper.getMobile(rank.getApproverId());
                        String randomId = getRandomId(strategyID, rank.getApproverId());
                        Sender.sendSMS(
                                Sender.CHECK_CODE,
                                new String[]{mobile},
                                new String[]{
                                        params.get("strategyName").toString(),
                                        String.valueOf(userGroupSize),
                                        sms_content,
                                        jobType,
                                        randomId,
                                        randomId,
                                }
                        );
                    }
                    smsApproveRankInfoMapper.insertSMSApproveRankInfo(rank);
                }
            }
            // 创建审核记录
            createApprove(params);

        }
    }

    /**
     * PUSH策略参数验证及业务逻辑
     *
     * @param params
     * @return
     */
    private void pushStrategy(Map<String, Object> params) {
        // 生成策略ID
        Date date = new Date();
        String strategyId = "PS" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        params.put("strategyId", strategyId);
        // 去掉标题中的换行
        if (null != params.get("pushTitle") && !"".equals(params.get("pushTitle"))) {
            String title = String.valueOf(params.get("pushTitle"));
            params.remove("pushTitle");
            title = title.replace("\n", "");
            params.put("pushTitle", title);
        }

        // 去掉文案中的换行
        if (null != params.get("pushContent") && !"".equals(params.get("pushContent"))) {
            String content = String.valueOf(params.get("pushContent"));
            params.remove("pushContent");
            content = content.replace("\n", "");
            params.put("pushContent", content);
        }
        // 已完成的人群当人群规模小于200时跳过审批
        if (params.get("userGroupStatus").equals(5)) {
            // 人群规模为必填参数
            if (null == params.get("clientUser")) {
                throw new MyException(StatusEnum.BUSINID, "请填写人群规模");
            }
            // 人群规模
            int userGroupSize = 0;
            if (null != params.get("groupId") && !"".equals(params.get("groupId"))) {
                userGroupSize = Integer.parseInt(params.get("clientUser").toString());
            } else {
                userGroupSize = 9999;
            }
            // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
            noApprove(params, userGroupSize);
        } else {
            if (null == params.get("approverId") || null == params.get("approverName")) {
                throw new MyException(StatusEnum.BUSINID, "请选择审核人");
            }
        }

    }

    /**
     * banner策略参数验证及业务逻辑
     *
     * @param params
     * @return
     */
    private void bannerStrategy(Map<String, Object> params) {
        // 生成策略ID
        Date date = new Date();
        String strategyId = "BY" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        params.put("strategyId", strategyId);
        // 已完成的人群当人群规模小于200时跳过审批
        bannerOrMusicJudgeUserGroup(params);

    }

    /**
     * banner和音乐之声人群判断
     *
     * @param params 数据信息
     */
    private void bannerOrMusicJudgeUserGroup(Map<String, Object> params) {
        if (params.get("userGroupStatus").equals(5)) {
            // 人群规模为必填参数
            if (null == params.get("clientUser") && null == params.get("deviceUser")) {
                throw new MyException(StatusEnum.BUSINID, "请填写人群规模");
            }
            // 人群规模
            int userGroupSize = maxValue(Integer.parseInt(String.valueOf(params.get("clientUser"))),
                    Integer.parseInt(String.valueOf(params.get("deviceUser"))));
            // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
            noApprove(params, userGroupSize);
        } else {
            if (null == params.get("approverId") || null == params.get("approverName")) {
                throw new MyException(StatusEnum.BUSINID, "请选择审核人");
            }
        }
    }

    /**
     * 音乐之声策略参数验证及业务逻辑
     *
     * @param params
     * @return
     */
    private void musicStrategy(Map<String, Object> params) {
        // 生成策略ID
        Date date = new Date();
        String strategyId = "YY" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        params.put("strategyId", strategyId);
        // 已完成的人群当人群规模小于200时跳过审批
        bannerOrMusicJudgeUserGroup(params);

    }

    /**
     * 弹窗策略参数验证及业务逻辑
     *
     * @param params
     * @return
     */
    private void popupStrategy(Map<String, Object> params) {
        // 生成策略ID
        Date date = new Date();
        String strategyId = "TQ" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        params.put("strategyId", strategyId);
        // 1- uid; 2- device;
        int popType = Integer.parseInt(String.valueOf(params.get("popupType")));
        // 人群规模
        int userGroupSize = 0;
        if (popType == 1) {
            // 人群规模为必填参数
            if (null == params.get("clientUser")) {
                throw new MyException(StatusEnum.BUSINID, "请填写人群规模");
            }
            userGroupSize = Integer.parseInt(params.get("clientUser").toString());
        }
        if (popType == 2) {
            // 人群规模为必填参数
            if (null == params.get("deviceUser")) {
                throw new MyException(StatusEnum.BUSINID, "请填写人群规模");
            }
            userGroupSize = Integer.parseInt(params.get("deviceUser").toString());
        }
        // 如果人群规模小于200，不需要审批，直接将状态定义为3- 未开始
        noApprove(params, userGroupSize);

    }

    /**
     * 消息通知参数校验
     *
     * @param params
     */
    private void msgNoticeStrategy(Map<String, Object> params) {
        // 生成策略ID
        Date date = new Date();
        String strategyId = "MN" + DateUtil.parseDateToStr(date, DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISSSSS);
        params.put("strategyId", strategyId);
        // 已完成的人群当人群规模小于200时跳过审批
        bannerOrMusicJudgeUserGroup(params);

    }

    /**
     * 创建审批记录
     *
     * @param params
     */
    public void createApprove(Map<String, Object> params) {
        if (null == params.get("strategyId")) {
            return;
        }
        ApproveHistory approve = new ApproveHistory();
        if (null != params.get("groupId") && !"".equals(params.get("groupId"))) {
            approve.setUserGroupName(params.get("groupName").toString());
        }
        approve.setStrategyId(params.get("strategyId").toString());
        approve.setStrategyName(params.get("strategyName").toString());
        approve.setStrategyType(Byte.valueOf(params.get("strategyType").toString()));
        approve.setApproverId(params.get("approverId").toString());
        approve.setApproverName(params.get("approverName").toString());
        // 1- 待审核
        approve.setApproveStatus(ApproveConstans.APPROVE_WAIT);
        // 创建人loginName
        approve.setCreatorId(params.get("creatorId").toString());
        // 创建人userName
        approve.setCreatorName(params.get("creatorName").toString());
        approve.setCreatorDepartment(params.get("creatorDepartment").toString());
        approve.setCreatorPhone(params.get("creatorPhone").toString());
        try {
            approveMapper.createApprove(approve);
        } catch (Exception e) {
            log.error("添加审核记录失败", e);
            throw new MyException(StatusEnum.ERROR, "添加审核记录失败");
        }
    }

    /**
     * 手动输入短信用户 1、立即发送短信 2、不存储在策略表中 3、不考虑黑白名单，录入的电话号码直接发送
     *
     * @param map
     * @return
     */
    @Override
    public ResultObject sendMsgForTest(Map<String, Object> map) {
        ResultObject res = new ResultObject();
        if (null == map.get("testPhones") || null == map.get("smsContent") || null == map.get("templateId")) {
            throw new MyException(StatusEnum.BUSINID, "短信名单不可为空");
        }
        // 手机号
        String testPhones = map.get("testPhones").toString();
        // 短信内容
        String content = map.get("smsContent").toString();
        // 短信模板ID
        String templateId = map.get("templateId").toString();
        if (map.get("sendWay") != null && map.get("sendWay").toString().equals("1")) {
            Sender.send2MegamarketSMS(testPhones, content);
            res.setMsg("短信发送成功");
            return res;
        }
        // 手动输入的短信名单
        String[] mobiles = testPhones.split(",");
        String[] params = getParams(content);
        // 发送短信
        Sender.sendSMS(templateId, mobiles, params);
        res.setMsg("短信发送成功");
        return res;
    }

    /**
     * 通过策略名称查询策略详情
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject queryStrategyDetailByName(Map<String, Object> params) {
        // 查询条件： 策略名称
        // String strategyName = String.valueOf(params.get("strategyName"));
        Map<String, Object> data = strategyMapper.queryStrategyDetailByName(params);
        ResultObject res = new ResultObject();
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        res.setData(data);
        return res;
    }

    /**
     * 提取{}中的参数并以数组形式返回
     *
     * @param str
     * @return
     */
    private String[] getParams(String str) {
        List<String> params = new ArrayList<>();
        // 提取{}中的参数
        Pattern pattern = Pattern.compile("(?<=\\{)[^\\}]+");
        Matcher matcher = pattern.matcher(str);
        while (matcher.find()) {
            params.add(matcher.group());
        }
        // 提取不到参数
        if (null == params || params.size() == 0) {
            return null;
        }
        // 生成String[]
        String[] tplVars = new String[params.size()];
        for (int i = 0; i < params.size(); i++) {
            tplVars[i] = params.get(i);
        }
        return tplVars;
    }

    /**
     * 求最大值
     *
     * @param a
     * @param b
     * @return
     */
    public static int maxValue(int a, int b) {
        return a > b ? a : b;
    }

    /**
     * 暂停策略执行
     *
     * @param params
     * @return
     */
    @Override
    public ResultObject pause(Map<String, Object> params) {
        // 策略ID不可为空
        if (null == params.get("strategyId")) {
            throw new MyException(StatusEnum.BUSINID, "策略ID不可为空");
        }
        try {
            // 中止策略执行
            strategyMapper.pause(params);
            ResultObject res = new ResultObject();
            res.setMsg("操作成功");
            return res;
        } catch (Exception e) {
            log.error("操作失败", e);
            throw new MyException(StatusEnum.ERROR, "操作失败");
        }
    }

    @Override
    public ResultObject pull(MultipartFile file, String groupId) {
        ResultObject res = new ResultObject();
        String filename = file.getOriginalFilename();
        File tofile = new File(FILE_RECODE_PATH, filename);
        // 读取redis客群用户
        int memberNum = Integer.valueOf(String.valueOf(redisTemplate.opsForSet().size(groupId + "-uid")));
        try {
            // 读取文件
            List<String> list = IOUtils.readLines(file.getInputStream());
            for (String i : list) {
                String[] st = i.split(",|\\|");
                if (st.length >= 2) {
                    String uid = st[0];
                    String rcode = st[1];
                    Boolean isMember = redisTemplate.opsForSet().isMember(groupId + "-uid", uid);
                    // 判断空指针
                    // 判断户是否是于人群一至
                    if (uid.isEmpty() || rcode.isEmpty() || memberNum != list.size() || !isMember) {
                        res.setCode(StatusEnum.BUSINID.getCode());
                        res.setMsg(StatusEnum.BUSINID.getMsg());
                        return res;
                    }
                } else {
                    res.setCode(StatusEnum.BUSINID.getCode());
                    res.setMsg(StatusEnum.BUSINID.getMsg());
                    return res;
                }
            }
            file.transferTo(tofile);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        Map<String, String> map = new HashMap<>(3);
        map.put("name", filename);
        map.put("ftpDir", FILE_RECODE_PATH);
        res.setCode(StatusEnum.SUCCESS.getCode());
        res.setMsg(StatusEnum.SUCCESS.getMsg());
        res.setData(map);
        return res;
    }

    @Override
    public ResultObject<String> revocation(Map<String, Object> params) {
        // 策略ID不可为空
        if (null == params.get("strategyId")) {
            throw new MyException(StatusEnum.BUSINID, "策略ID不可为空");
        }
        // 执行状态不可为空
        String status = params.get("executeStatus").toString();
        if (status == null) {
            throw new MyException(StatusEnum.BUSINID, "策略执行状态不可为空");
        }
        // 仅【1-待审核】状态下的策略可以撤回
        Byte executeStatus = Byte.parseByte(status);
        if (!executeStatus.equals(StrategyConstants.EXECUTE_CHECKING)) {
            throw new MyException(StatusEnum.BUSINID, "当前策略不可撤回");
        }
        params.put("revocationTime",
                DateUtil.parseDateToStr(new Date(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS));
        try {
            strategyMapper.revocationStrategyById(params);
        } catch (Exception e) {
            log.error("撤回策略失败", e);
            throw new MyException(StatusEnum.ERROR, "撤回策略失败");
        }
        return new ResultObject<String>("0000", "撤回成功", "已成功撤回该策略！");
    }

    /**
     * 将短信策略发送给大营销平台审核
     *
     * @param params
     */
    @Override
    public boolean sendToMegamarketAudit(Map<String, Object> params) throws IOException {
        MiguSubCompanyCampDto miguSubCompanyCampDto = new MiguSubCompanyCampDto();
        miguSubCompanyCampDto.setBlackUser(1);
        miguSubCompanyCampDto.setCampsegDesc(params.get("remarks") == null ? "1"
                : StringUtils.isNotBlank(params.get("remarks").toString()) ? params.get("remarks").toString() : "1");
        String campsegId = params.get("strategyId").toString();
        miguSubCompanyCampDto.setCampsegId(campsegId);
        miguSubCompanyCampDto.setCampsegName(params.get("strategyName").toString());
        // 父id，要与策略id不一致
        String campsegPid =
                params.get("strategyGroupId").toString() + (int) ((Math.random() * 9 + 1) * Math.pow(10, 4 - 1));
        miguSubCompanyCampDto.setCampsegPid(campsegPid);
        // 使用服务云自己的用户id
        miguSubCompanyCampDto.setCreateLoginName(params.get("creatorId").toString());
        // 看看是不是统一服务平台的客群
        HashMap<String, Object> labelUserGroup = popupMapper.isLabelUserGroup(params.get("groupId").toString());
        if (null != labelUserGroup && labelUserGroup.size() > 0) {
            miguSubCompanyCampDto.setCustgroupId(params.get("groupId").toString());
        }
        // 短信下发去重天数，暂时不用去重
        miguSubCompanyCampDto.setDistictDays(0);
        String endDate = null;
        String startDate = null;
        if (params.get("jobType").toString().equals("1")) {
            Date now = new Date();
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(now);
            rightNow.add(Calendar.MINUTE, 10);
            startDate = DateUtil.parseDateToStr(rightNow.getTime(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
            rightNow.add(Calendar.MINUTE, 20);
            endDate = DateUtil.parseDateToStr(rightNow.getTime(), DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS);
        } else if (params.get("jobType").toString().equals("2")) {
            endDate = params.get("startTime").toString();
            startDate = params.get("startTime").toString();
        } else {
            endDate = params.get("endTime").toString();
            startDate = params.get("startTime").toString();
        }
        miguSubCompanyCampDto.setEndDate(endDate);
        miguSubCompanyCampDto.setStartDate(startDate);
        HashMap<String, String> megamarket =
                megamarketMapper.qryMegamarketInfoByID(Integer.valueOf(String.valueOf(params.get("smsSendPort"))));
        // miguSubCompanyCampDto.setAdivId(StrategyConstants.MEGAMARKET_ADIVID);
        miguSubCompanyCampDto.setAdivId(megamarket.get("adivId"));
        // miguSubCompanyCampDto.setShortUrl(params.get("shortUrl").toString());
        // 短信内容不能超过100
        miguSubCompanyCampDto.setSmsContent(params.get("smsContent").toString().length() >= 100
                ? params.get("smsContent").toString().substring(0, 99) : params.get("smsContent").toString());
        miguSubCompanyCampDto.setSubCompanyCode(StrategyConstants.MEGAMARKET_SUBCOMPANYCODE);
        // 大营销账户组编码，由大营销平台定义
        miguSubCompanyCampDto.setUserGroupId(StrategyConstants.MEGAMARKET_USERGROUPID);
        miguSubCompanyCampDto.setCampsegStatId(StrategyConstants.MEGAMARKET_CAMPSEGSTATID_CHECKING);

        log.info("{}发送的body miguSubCompanyCampDto:{}", params.get("strategyId").toString(),
                miguSubCompanyCampDto.toString());

        String url = MEGAMARKET_IP + MEGAMARKET_SUBCOMPANYCAMPSYNC2MARKETING;

        log.info("服务端URL: {}", url);

        String response = HttpUtils.doPost(url, JsonUtils.obj2Json(miguSubCompanyCampDto), null);
        log.info("HTTP请求结果：{}", response);
        Map responseMap = JsonUtils.json2Obj(response, HashMap.class);
        if (!responseMap.get("status").toString().equals("SUCCESS")) {
            try {
                String[] tels = new String[1];
                tels[0] = String.valueOf(params.get("creatorPhone"));
                String[] vals = new String[3];
                vals[0] = String.valueOf(params.get("strategyName"));
                vals[1] = "短信";
                vals[2] = "大营销平台默认审核失败";
                Sender.sendSMS("20100066", tels, vals);
                return true;
            } catch (Exception e) {
                log.error("发送通知短信失败：{}", params);
                throw new MyException(StatusEnum.SMS_SEND_MEGAMARKET_AUDIT, "同步到大营销平台接口调用异常");
            }
        }
        return false;
    }

    /**
     * 离线短信统一审核能力接入
     *
     * @param params
     */
    private void smsUnifyAudit(Map<String, Object> params) {
        if ("1".equals(String.valueOf(params.get("isUnifyAudit")))) {
            //默认策略为待审核状态
            params.put("executeStatus", StrategyConstants.EXECUTE_CHECKING);
            String dataId = params.get("strategyId").toString() + "-" + DateUtil.parseDateToStr(new Date(), DateUtil.DATE_TIME_FORMAT_YYYYMMDDHHMISS);
            AuditData data = AuditData.builder()
                    .dataId(dataId)
                    .data(params.get("smsContent").toString())
                    .dataType("短信内容")
                    .description(params.get("remarks").toString())
                    .priority("HIGH")
                    .build();
            unifyAuditService.auditSend(params.get("strategyId").toString(), Collections.singletonList(data));
        }
    }


    public String getRandomId(String strategyId, String approvalId) {
        Random random = new Random();
        String randomNumber;
        Map map;
        do {
            randomNumber = String.valueOf(random.nextInt(9000) + 1000);
            map = strategyMapper.selectNumber(randomNumber);
        } while (map != null);
        strategyMapper.insertNumber(randomNumber, strategyId, approvalId);
        return randomNumber;
    }


}